home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / exampleCode / GLX / DBglxwidgetOpenGL / GlxDraw.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  65.9 KB  |  2,214 lines

  1. static char rcsid[]=
  2.  "$Header: /usr/people/millard/DBglxwidget/RCS/GlxDraw.c,v 1.2 1994/01/01 22:31:41 millard Exp millard $";
  3. /*
  4.  *    These files are for informational purposes and can demonstrate how
  5.  *   to write your own mixed-mode GL-based widgets.  However SGI does not
  6.  *   guarantee that this source code absolutely matches the GLxDraw
  7.  *   widget that is shipped as part of the system.
  8.  *
  9.  *   New Version by Chris Carlson and Ed Millard
  10.  *   supports switching between single and double buffering
  11.  */
  12.  
  13. /***********************************************************
  14. Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts,
  15. and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
  16.  
  17.                         All Rights Reserved
  18.  
  19. Permission to use, copy, modify, and distribute this software and its 
  20. documentation for any purpose and without fee is hereby granted, 
  21. provided that the above copyright notice appear in all copies and that
  22. both that copyright notice and this permission notice appear in 
  23. supporting documentation, and that the names of Digital or MIT not be
  24. used in advertising or publicity pertaining to distribution of the
  25. software without specific, written prior permission.  
  26.  
  27. DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  28. ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
  29. DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
  30. ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  31. WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
  32. ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  33. SOFTWARE.
  34.  
  35. ******************************************************************/
  36.  
  37.  
  38. /*------------------------------------------------------------------------
  39.  *  III   N   N   CCC   L      U   U  DDDD   EEEEE   SSS
  40.  *   I    NN  N  C   C  L      U   U  D   D  E      S   S
  41.  *   I    NN  N  C      L      U   U  D   D  E      S
  42.  *   I    N N N  C      L      U   U  D   D  EEE     SSS
  43.  *   I    N  NN  C      L      U   U  D   D  E          S
  44.  *   I    N  NN  C   C  L      U   U  D   D  E      S   S
  45.  *  III   N   N   CCC   LLLLL   UUU   DDDD   EEEEE   SSS
  46.  *------------------------------------------------------------------------*/
  47.  
  48. #ifdef DEBUG
  49. #include <stdio.h>
  50. #endif
  51.  
  52. #include <X11/IntrinsicP.h>
  53. #include <X11/StringDefs.h>
  54.  
  55. #include <X11/Xatom.h>
  56. #include <X11/Xutil.h>
  57. #ifdef USE_GL
  58. #include <gl/get.h>
  59. #else
  60. #endif /* USE_GL */
  61.  
  62. #ifdef __GLX_MOTIF
  63. #include <Xm/XmP.h>
  64.  
  65. #ifdef SVR4
  66. #include <Xm/PrimitiveP.h>
  67. #endif
  68.  
  69. #include "GlxMDrawP.h"
  70.  
  71. #else            /* not __GLX_MOTIF */
  72.  
  73. #include "GlxDrawP.h"
  74.  
  75. #endif            /* __GLX_MOTIF */
  76.  
  77. /*------------------------------------------------------------------------
  78.  * DDDD   EEEEE  FFFFF   III   N   N  EEEEE   SSS
  79.  * D   D  E      F        I    NN  N  E      S   S
  80.  * D   D  E      F        I    NN  N  E      S
  81.  * D   D  EEE    FFF      I    N N N  EEE     SSS
  82.  * D   D  E      F        I    N  NN  E          S
  83.  * D   D  E      F        I    N  NN  E      S   S
  84.  * DDDD   EEEEE  F       III   N   N  EEEEE   SSS
  85.  *------------------------------------------------------------------------*/
  86.  
  87. #ifdef __GLX_MOTIF
  88. /* The MOTIF version differs only in the inclusion of the primitive
  89.  * widget class and in a vew variable and type name differences.
  90.  * Rather than put ifdefs all over the place, we just use a few defines
  91.  * to make it use motif types and names
  92.  */
  93. #define GlxDrawWidget        GlxMDrawWidget
  94. #define GlxDrawClassRec        GlxMDrawClassRec
  95. #define glxDrawClassRec        glxMDrawClassRec
  96. #define glxDrawWidgetClass    glxMDrawWidgetClass
  97. #define GlxDrawRec        GlxMDrawRec
  98. #endif /* __GLX_MOTIF */
  99.  
  100. #define MAX_CONFIG 128
  101.  
  102. /*----
  103.  * Explanation of DEBUG definitions:
  104.  *    bitmap    enables
  105.  *    ------    -------
  106.  *    defnd    Calls XSynchronize before doing 'Initialize'.
  107.  *    0x0002    Print colormap info
  108.  *    0x0004    Print window IDs
  109.  *    0x0008    Print visual info
  110.  *    0xFFFE    Will print info useful to all of the above
  111.  *----*/
  112.  
  113. /*------------------------------------------------------------------------
  114.  * M   M   AAA    CCC   RRRR    OOO    SSS
  115.  * MM MM  A   A  C   C  R   R  O   O  S   S
  116.  * MM MM  A   A  C      R   R  O   O  S
  117.  * M M M  AAAAA  C      RRRR   O   O   SSS
  118.  * M   M  A   A  C      R R    O   O      S
  119.  * M   M  A   A  C   C  R  R   O   O  S   S
  120.  * M   M  A   A   CCC   R   R   OOO    SSS
  121.  *------------------------------------------------------------------------*/
  122.  
  123. #define offset(field) XtOffset(GlxDrawWidget, glxDraw.field)
  124.  
  125. /*------------------------------------------------------------------------
  126.  * L       OOO    CCC    AAA   L       SSS
  127.  * L      O   O  C   C  A   A  L      S   S
  128.  * L      O   O  C      A   A  L      S
  129.  * L      O   O  C      AAAAA  L       SSS
  130.  * L      O   O  C      A   A  L          S
  131.  * L      O   O  C   C  A   A  L      S   S
  132.  * LLLLL   OOO    CCC   A   A  LLLLL   SSS
  133.  *------------------------------------------------------------------------*/
  134.  
  135. static char defaultTranslations[] =
  136.     "<KeyDown>:    glxInput() \n\
  137.      <KeyUp>:    glxInput() \n\
  138.      <BtnDown>: glxInput() \n\
  139.      <BtnUp>:   glxInput() \n\
  140.      <BtnMotion>: glxInput() ";
  141.  
  142. static void glxInput();
  143. static void auxwindow_destroyed();
  144.  
  145. #ifdef USE_GL
  146. static GLXconfig default_config[] = {{0,0,0}};
  147. #else
  148. static int default_config[] = {
  149.     GLX_RGBA,
  150.     GLX_RED_SIZE,3,
  151.     GLX_BLUE_SIZE,3,
  152.     GLX_GREEN_SIZE,3,
  153.     GLX_DEPTH_SIZE,12,
  154.     GLX_DOUBLEBUFFER,
  155.     None,
  156. };
  157. #endif /* USE_GL */
  158.  
  159. static XtActionsRec actions[] = {
  160.     { "glxInput", glxInput },    /* key or mouse input */
  161. };
  162.  
  163. static XtResource resources[] = {
  164. #ifdef USE_GL
  165.   {GlxNglxConfig, GlxCGlxConfig, GlxRGlxConfig, sizeof(GLXconfig *),
  166.        offset(config),
  167.        XtRImmediate, (caddr_t) default_config},
  168. #else
  169.   {GlxNglxConfig, GlxCGlxConfig, GlxRGlxConfig, sizeof(int *),
  170.        offset(config),
  171.        XtRImmediate, (caddr_t) default_config},
  172.  
  173.   {GlxNglxContext, GlxCGlxContext, GlxRGlxContext, sizeof (GLXContext *),
  174.        offset(context),
  175.        XtRImmediate, (caddr_t) 0},
  176. #endif /* USE_GL */
  177.  
  178.   {GlxNginitCallback, GlxCCallback, XtRCallback, sizeof (XtCallbackList),
  179.        offset(ginit_callback), XtRImmediate, (caddr_t) NULL},
  180.  
  181.   {GlxNinputCallback, GlxCCallback, XtRCallback, sizeof (XtCallbackList),
  182.        offset(input_callback), XtRImmediate, (caddr_t) NULL},
  183.  
  184.   {GlxNresizeCallback, GlxCCallback, XtRCallback, sizeof (XtCallbackList),
  185.        offset(resize_callback), XtRImmediate, (caddr_t) NULL},
  186.  
  187.   {GlxNexposeCallback, GlxCCallback, XtRCallback, sizeof (XtCallbackList),
  188.        offset(expose_callback), XtRImmediate, (caddr_t) NULL},
  189.  
  190.   {GlxNvisualInfo, GlxCVisualInfo, GlxRVisualInfo, sizeof (XVisualInfo *),
  191.        offset(visualInfo), XtRImmediate, (caddr_t) NULL},
  192.  
  193.   {GlxNoverrideColormap, GlxCOverrideColormap, XtRBoolean, sizeof (Boolean),
  194.        offset(override_colormap), XtRImmediate, (caddr_t) TRUE},
  195.  
  196.   {GlxNuseOverlay, GlxCUseOverlay, XtRBoolean, sizeof (Boolean),
  197.        offset(overlay_info.exists), XtRImmediate, (caddr_t) FALSE},
  198.  
  199.   {GlxNoverlayWindow, GlxCWindow, XtRWindow, sizeof (Window),
  200.        offset(overlay_info.window), XtRImmediate, (caddr_t) 0},
  201.  
  202.   {GlxNoverlayColormap, GlxCColormap, XtRColormap, sizeof (Colormap),
  203.        offset(overlay_info.colormap), XtRImmediate, (caddr_t) 0},
  204.  
  205.   {GlxNoverlayDepth, GlxCDepth, XtRInt, sizeof (int),
  206.        offset(overlay_info.depth), XtRImmediate, (caddr_t) 0},
  207.  
  208.   {GlxNoverlayVisual, GlxCVisualInfo, GlxRVisualInfo, sizeof (XVisualInfo *),
  209.        offset(overlay_info.visualInfo), XtRImmediate, (caddr_t) 0},
  210. #ifndef USE_GL
  211.   {GlxNoverlayGlxConfig, GlxCGlxConfig, GlxRGlxConfig, sizeof(int *),
  212.        offset(overlay_info.config),
  213.        XtRImmediate, (caddr_t) 0},
  214.  
  215.   {GlxNoverlayGlxContext, GlxCGlxContext, GlxRGlxContext, sizeof (GLXContext *),
  216.        offset(overlay_info.context), XtRImmediate, (caddr_t) 0},
  217. #endif
  218.  
  219.   {GlxNoverlayExposeCallback, GlxCCallback, XtRCallback,
  220.        sizeof (XtCallbackList),
  221.        offset(overlay_info.expose_callback), XtRImmediate, (caddr_t) NULL},
  222.  
  223.   {GlxNuseUnderlay, GlxCUseUnderlay, XtRBoolean, sizeof (Boolean),
  224.        offset(underlay_info.exists), XtRImmediate, (caddr_t) FALSE},
  225.  
  226.   {GlxNunderlayWindow, GlxCWindow, XtRWindow, sizeof (Window),
  227.        offset(underlay_info.window), XtRImmediate, (caddr_t) 0},
  228.  
  229.   {GlxNunderlayColormap, GlxCColormap, XtRColormap, sizeof (Colormap),
  230.        offset(underlay_info.colormap), XtRImmediate, (caddr_t) 0},
  231.  
  232.   {GlxNunderlayDepth, GlxCDepth, XtRInt, sizeof (int),
  233.        offset(underlay_info.depth), XtRImmediate, (caddr_t) 0},
  234.  
  235.   {GlxNunderlayVisual, GlxCVisualInfo, GlxRVisualInfo, sizeof (XVisualInfo *),
  236.        offset(underlay_info.visualInfo), XtRImmediate, (caddr_t) 0},
  237.  
  238.   {GlxNunderlayExposeCallback, GlxCCallback, XtRCallback,
  239.        sizeof (XtCallbackList),
  240.        offset(underlay_info.expose_callback), XtRImmediate, (caddr_t) NULL},
  241.  
  242.   {GlxNusePopup, GlxCUsePopup, XtRBoolean, sizeof (Boolean),
  243.        offset(popup_info.exists), XtRImmediate, (caddr_t) FALSE},
  244.  
  245.   {GlxNpopupWindow, GlxCWindow, XtRWindow, sizeof (Window),
  246.        offset(popup_info.window), XtRImmediate, (caddr_t) 0},
  247.  
  248.   {GlxNpopupColormap, GlxCColormap, XtRColormap, sizeof (Colormap),
  249.        offset(popup_info.colormap), XtRImmediate, (caddr_t) 0},
  250.  
  251.   {GlxNpopupDepth, GlxCDepth, XtRInt, sizeof (int),
  252.        offset(popup_info.depth), XtRImmediate, (caddr_t) 0},
  253.  
  254.   {GlxNpopupVisual, GlxCVisualInfo, GlxRVisualInfo, sizeof (XVisualInfo *),
  255.        offset(popup_info.visualInfo), XtRImmediate, (caddr_t) 0},
  256.  
  257.   {GlxNpopupExposeCallback, GlxCCallback, XtRCallback, sizeof (XtCallbackList),
  258.        offset(popup_info.expose_callback), XtRImmediate, (caddr_t) NULL},
  259.  
  260.   {GlxNmainWindow, GlxCWindow, XtRWindow, sizeof (Window),
  261.        offset (mainWindow), XtRImmediate, (caddr_t) 0},
  262.  
  263.   {GlxNprovideSingleBuffer, GlxCProvideSingleBuffer, XtRBoolean,
  264.        sizeof (Boolean),
  265.        offset(provide_Sbuffer), XtRImmediate, (caddr_t) NULL},
  266.  
  267.   {GlxNsingleBuffer, GlxCSingleBuffer, XtRBoolean, sizeof (Boolean),
  268.        offset(single_buffer), XtRImmediate, (caddr_t) NULL},
  269.  
  270.   {GlxNprovideStereoBuffer, GlxCProvideStereoBuffer, XtRBoolean,
  271.        sizeof (Boolean),
  272.        offset(provide_StereoBuffer), XtRImmediate, (caddr_t) NULL},
  273.  
  274.   {GlxNstereoBuffer, GlxCStereoBuffer, XtRBoolean, sizeof (Boolean),
  275.        offset(stereo_buffer), XtRImmediate, (caddr_t) NULL},
  276.  
  277.   {GlxNaltColormap, GlxCColormap, XtRColormap, sizeof (Colormap),
  278.        offset(alt_colormap), XtRImmediate, (caddr_t)0},
  279.  
  280. #ifdef __GLX_MOTIF
  281.   /* Primitive resources */
  282.   {XmNtraversalOn, XmCTraversalOn, XmRBoolean, sizeof (Boolean),
  283.        XtOffset (GlxDrawWidget, primitive.traversal_on), XmRImmediate,
  284.        (caddr_t) FALSE},
  285.   
  286.   {XmNhighlightOnEnter, XmCHighlightOnEnter, XmRBoolean, sizeof (Boolean),
  287.        XtOffset (GlxDrawWidget, primitive.highlight_on_enter), XmRImmediate,
  288.        (caddr_t) FALSE},
  289.   
  290.   {XmNshadowThickness, XmCShadowThickness, XmRHorizontalDimension,
  291.        sizeof (Dimension),
  292.        XtOffset (GlxDrawWidget, primitive.shadow_thickness), XmRImmediate,
  293.        (caddr_t) 0},
  294.   
  295.   {XmNhighlightThickness, XmCHighlightThickness, XmRHorizontalDimension,
  296.        sizeof (Dimension),
  297.        XtOffset (GlxDrawWidget, primitive.highlight_thickness), XmRImmediate,
  298.        (caddr_t) 0},
  299. #endif            /* __GLX_MOTIF */
  300.   
  301. #undef offset
  302. };
  303.  
  304. static void
  305.     ClassInitialize(),
  306.     Initialize(),
  307.     Realize(),
  308.     CreateWindow(),
  309.     Redraw(),
  310.     Resize(),
  311.     Destroy();
  312. static Boolean
  313.     SetValues();
  314.  
  315. /*------------------------------------------------------------------------
  316.  *  GGG   L       OOO   BBBB    AAA   L       SSS
  317.  * G   G  L      O   O  B   B  A   A  L      S   S
  318.  * G      L      O   O  B   B  A   A  L      S
  319.  * G      L      O   O  BBBB   AAAAA  L       SSS
  320.  * G GGG  L      O   O  B   B  A   A  L          S
  321.  * G   G  L      O   O  B   B  A   A  L      S   S
  322.  *  GGG   LLLLL   OOO   BBBB   A   A  LLLLL   SSS
  323.  *------------------------------------------------------------------------*/
  324.  
  325. GlxDrawClassRec glxDrawClassRec =
  326. {
  327.   { /* core fields */
  328. #ifdef __GLX_MOTIF
  329.     /* superclass        */    (WidgetClass) &xmPrimitiveClassRec,
  330.     /* class_name        */    "GlxMDraw",
  331. #else /* not __GLX_MOTIF */
  332.     /* superclass        */    (WidgetClass) &widgetClassRec,
  333.     /* class_name        */    "GlxDraw",
  334. #endif /* __GLX_MOTIF */
  335.     /* widget_size        */    sizeof(GlxDrawRec),
  336.     /* class_initialize        */    ClassInitialize,
  337.     /* class_part_initialize    */    NULL,
  338.     /* class_inited        */    FALSE,
  339.     /* initialize        */    Initialize,
  340.     /* initialize_hook        */    NULL,
  341.     /* realize            */    Realize,
  342.     /* actions            */    actions,
  343.     /* num_actions        */    XtNumber(actions),
  344.     /* resources        */    resources,
  345.     /* num_resources        */    XtNumber(resources),
  346.     /* xrm_class        */    NULLQUARK,
  347.     /* compress_motion        */    TRUE,
  348.     /* compress_exposure    */    TRUE,
  349.     /* compress_enterleave    */    TRUE,
  350.     /* visible_interest        */    TRUE,
  351.     /* destroy            */    Destroy,
  352.     /* resize            */    Resize,
  353.     /* expose            */    Redraw,
  354.     /* set_values        */    SetValues,
  355.     /* set_values_hook        */    NULL,
  356.     /* set_values_almost    */    XtInheritSetValuesAlmost,
  357.     /* get_values_hook        */    NULL,
  358.     /* accept_focus        */    NULL,
  359.     /* version            */    XtVersion,
  360.     /* callback_private        */    NULL,
  361.     /* tm_table            */    defaultTranslations,
  362.     /* query_geometry        */    XtInheritQueryGeometry,
  363.     /* display_accelerator    */    XtInheritDisplayAccelerator,
  364.     /* extension        */    NULL
  365.   },
  366. #ifdef __GLX_MOTIF /* primitive resources */
  367.   {
  368.     /* border_highlight        */    XmInheritBorderHighlight,
  369.     /* border_unhighlight    */    XmInheritBorderUnhighlight,
  370.     /* translations        */    XtInheritTranslations,
  371.     /* arm_and_activate        */    NULL,
  372.     /* get_resources        */    NULL,
  373.     /* num get_resources    */    0,
  374.     /* extension        */    NULL,                
  375.   }
  376. #endif /* __GLX_MOTIF */
  377. };
  378. WidgetClass glxDrawWidgetClass = (WidgetClass)&glxDrawClassRec;
  379.  
  380. /*------------------------------------------------------------------------
  381.  * error
  382.  *------------------------------------------------------------------------*/
  383.  
  384. static char *gl_errs[] = {
  385.     "No error", "No context", "No display", "No window", "No graphics",
  386.     "Not top", "No visual", "Buffer size too small", "Bad window",
  387. };
  388.  
  389. static void  error(w,string)
  390.   Widget w;
  391.   char *string;
  392. {
  393.     char buf[100];
  394. #ifdef __GLX_MOTIF
  395.     sprintf (buf, "GlxMDraw: %s\n", string);
  396. #else
  397.     sprintf (buf, "GlxDraw: %s\n", string);
  398. #endif
  399.     XtAppError(XtWidgetToApplicationContext(w), buf);
  400. }
  401.  
  402. /*------------------------------------------------------------------------
  403.  * warning
  404.  *------------------------------------------------------------------------*/
  405.  
  406. static void warning(w,string)
  407.   Widget w;
  408.   char *string;
  409. {
  410.     char buf[100];
  411. #ifdef __GLX_MOTIF
  412.     sprintf (buf, "GlxMDraw: %s\n", string);
  413. #else
  414.     sprintf (buf, "GlxDraw: %s\n", string);
  415. #endif
  416.     XtAppWarning(XtWidgetToApplicationContext(w), buf);
  417. }
  418.  
  419. /*------------------------------------------------------------------------
  420.  * Documentation
  421.  *    I thought it would be appropriate to document some of the more
  422.  *    confusing stuff here.  It's actually here to help me remember
  423.  *    what's going on.
  424.  *
  425.  *    ClassInitialize
  426.  *      [Called by: X]
  427.  *        Called when widgets of this class are to be initialized.
  428.  *
  429.  *    Initialize
  430.  *      [Called by: X]
  431.  *        Called to initialize the widget.
  432.  *        1.  Fills in default values for widget structure.
  433.  *        2.  Uses the resources to figure out visuals and
  434.  *            colormaps to be used.
  435.  *        3.  If both single and double buffered windows are
  436.  *            to exist, fill in all the same sort of stuff
  437.  *            for the second window.
  438.  *
  439.  *    SetValuesAux
  440.  *      [Called by:    SetAux]
  441.  *      [Calls:    XChangeWindowAttributes]
  442.  *        Used to set up common resources for overlay, underlay
  443.  *        and popup windows.  Calls XChangeWindowAttributes for
  444.  *        a change in colormaps.
  445.  *
  446.  *    SetNewWindow
  447.  *      [Called by:    SetValues]
  448.  *      [Calls:    XGetGeometry]
  449.  *      [        GLXwinset]
  450.  *      [        XResizeWindow]
  451.  *      [        XMapWindow]
  452.  *      [        ResizeAux]
  453.  *        Used to switch from single/double buffer window to
  454.  *        double/single buffer window.  Gets information about
  455.  *        the current window and sets the same info in the new
  456.  *        window.
  457.  *
  458.  *        Things that are maintained here:
  459.  *          mmode [with all matricies]    lsbackup
  460.  *          displaymode            lsrepeat
  461.  *          backface            lstyle
  462.  *          cmmode            pattern
  463.  *          color                scrmask
  464.  *          map                sm (shading model)
  465.  *          cursor            writemask
  466.  *          dcm (depthcue)        geometry
  467.  *          font
  468.  *    SetAux
  469.  *      [Called by:    SetValues]
  470.  *      [Calls:    SetValuesAux]
  471.  *        Used to cal SetValuesAux for each of the overlay,
  472.  *        underlay and popup planes.
  473.  *
  474.  *    SetValues
  475.  *      [Called by:    X]
  476.  *      [Calls:    SetAux]
  477.  *      [        XUnmapWindow]
  478.  *      [        SetNewWindow]
  479.  *        Called to change any resources.
  480.  *
  481.  *    RealizeAux
  482.  *      [Called by:    Realize]
  483.  *      [Calls:    XCreateWindow]
  484.  *      [        XMapWindow]
  485.  *      [        XSelectInput]
  486.  *      [        _XtRegisterWindow]
  487.  *        Used to setup and realize each of the overlay, underlay
  488.  *        and/or popup windows.
  489.  *
  490.  *    RealizeAuxDup
  491.  *      [Called by:    RealizeDup]
  492.  *      [Calls:    XCreateWindow]
  493.  *      [        XMapWindow]
  494.  *      [        XSelectInput]
  495.  *      [        _XtRegisterWindow]
  496.  *        Identical to RealizeAux except to be used to set up
  497.  *        these windows for the secondary window (single/double
  498.  *        buffered window).
  499.  *
  500.  *    RealizeDup
  501.  *      [Called by:    Realize]
  502.  *      [Calls:    XCreateColormap*]
  503.  *      [        XCreateWindow]
  504.  *      [        XSelectInput]
  505.  *      [        _XtRegisterWindow]
  506.  *      [        XSetWMColormapWindows]
  507.  *      [        RealizeAuxDup]
  508.  *      [        GLXlink]
  509.  *        Basically, this is a duplicate of Realize except it
  510.  *        sets up the second window.
  511.  *
  512.  *    Realize
  513.  *      [Called by:    X]
  514.  *      [Calls:    XQueryColors*]
  515.  *      [        XtCreateWindow]
  516.  *      [        RealizeAux]
  517.  *      [        GLXlink]
  518.  *      [        RealizeDup]
  519.  *      [        GLXwinset]
  520.  *      [        XtAddEventHandler]
  521.  *      [        XtCallCallbackList]
  522.  *        Does all the functions required to actually bring the
  523.  *        window up.
  524.  *
  525.  *    Redraw
  526.  *      [Called by:    X]
  527.  *
  528.  *    ResizeCallback
  529.  *
  530.  *    ResizeAux
  531.  *
  532.  *    ResizeDup
  533.  *
  534.  *    Resize
  535.  *      [Called by:    X]
  536.  *
  537.  *    Destroy
  538.  *      [Called by:    X]
  539.  *
  540.  *    glxInput
  541.  *
  542.  *    auxwindow_destroyed
  543.  *
  544.  *    GlxCreateMDraw
  545.  *      [Called by:    User]
  546.  *
  547.  *  * = Commented out
  548.  *------------------------------------------------------------------------*/
  549.  
  550.  
  551. /*------------------------------------------------------------------------
  552.  * ClassInitialize
  553.  *------------------------------------------------------------------------*/
  554.  
  555. static void ClassInitialize()
  556. {
  557. }
  558.  
  559. #ifndef USE_GL
  560. /*------------------------------------------------------------------------ 
  561.  * Choose an OpenGL visual and create a colormap for it
  562.  *------------------------------------------------------------------------*/
  563. static void InitializeOpenGLVisual (glw, info, info_overlay)
  564.   GlxDrawWidget glw;
  565.   GlxDrawWindowInfo *info, *info_overlay;
  566. {
  567.     GlxDrawWindowInfo *curWindowInfo;
  568.     int i;
  569.  
  570.     for(i = 0 ; i < 2 ; i++)
  571.     {
  572.         if(i == 0)
  573.         {
  574.             curWindowInfo = info;
  575.             if(!curWindowInfo->config)
  576.                  curWindowInfo->config = default_config;
  577.         }else{
  578.             curWindowInfo = info_overlay;
  579.         }
  580.  
  581.         if(curWindowInfo->config)
  582.         {
  583.             curWindowInfo->exists = TRUE;
  584.             curWindowInfo->visualInfo = glXChooseVisual(XtDisplay (glw),
  585.                     XScreenNumberOfScreen (XtScreen (glw)),
  586.                                 curWindowInfo->config);
  587.             if (!curWindowInfo->visualInfo)
  588.             {
  589.                 error(glw, "glXChooseVisual failed");
  590.                 return;
  591.             }
  592.             curWindowInfo->colormap = XCreateColormap(XtDisplay (glw),
  593.                                 RootWindow(XtDisplay (glw),
  594.                                      curWindowInfo->visualInfo->screen),
  595.                                 curWindowInfo->visualInfo->visual,
  596.                                 AllocNone);
  597.             curWindowInfo->depth = curWindowInfo->visualInfo->depth;
  598.         }
  599.     }
  600. }
  601. #endif
  602.  
  603. /*------------------------------------------------------------------------
  604.  * InitializeDup
  605.  *    Called to create the second window when both single and double
  606.  *    buffered windows are wanted.
  607.  *------------------------------------------------------------------------*/
  608.  
  609. static void InitializeDup (new, secondary, config)
  610.   GlxDrawWidget new;
  611.   GlxDrawBuffer *secondary;
  612. #ifdef USE_GL
  613.   GLXconfig *config;
  614. #else
  615.   int       *config;
  616. #endif /* USE_GL */
  617. {
  618. #ifdef USE_GL
  619.     GLXconfig        *newConfig, *tmpConfig;
  620. #else
  621.     int         *newConfig, *tmpConfig;
  622. #endif  /* USE_GL */
  623.     GlxDrawWindowInfo    *curWindowInfo;
  624.     XVisualInfo        tmpl;
  625.     int            nret;
  626.  
  627.     /*----
  628.      * Initialize secondary window information
  629.      *----*/
  630.     bzero (&secondary->info, sizeof (GlxDrawWindowInfo));
  631.     curWindowInfo = &secondary->info;
  632.     curWindowInfo->exists = True;
  633.     if (!new->glxDraw.override_colormap)
  634.     curWindowInfo->colormap = new->glxDraw.alt_colormap;
  635.  
  636.     /*----
  637.      * Make a duplicate GLwindow for switch to double
  638.      * buffering
  639.      *----*/
  640.  
  641. #ifdef USE_GL
  642.     newConfig = GLXgetconfig (XtDisplay (new),
  643.                   XScreenNumberOfScreen (XtScreen (new)),
  644.                   config);
  645.     if (!newConfig)
  646.     {
  647.     error (new, "Unable to get second visual");
  648.     return;
  649.     }
  650.     secondary->config = newConfig;
  651.  
  652.     for (tmpConfig = newConfig; tmpConfig->buffer; tmpConfig++)
  653.     {
  654.     if (tmpConfig->buffer == GLX_NORMAL)
  655.     {
  656.         switch (tmpConfig->mode)
  657.         {
  658.           case GLX_COLORMAP:
  659.         if (!curWindowInfo->colormap)
  660.             curWindowInfo->colormap = (Colormap)tmpConfig->arg;
  661.         break;
  662.           case GLX_VISUAL:
  663.         tmpl.visualid = tmpConfig->arg;
  664.         tmpl.screen   = XScreenNumberOfScreen (XtScreen (new));
  665.         curWindowInfo->visualInfo =
  666.             XGetVisualInfo (XtDisplay(new),
  667.                     VisualScreenMask|VisualIDMask,
  668.                     &tmpl, &nret);
  669.         if (!curWindowInfo->visualInfo)
  670.             error (new,"Couldn't get visual");
  671.         curWindowInfo->depth =
  672.             curWindowInfo->visualInfo->depth;
  673.         break;
  674.         }
  675.     }
  676.     }
  677. #else
  678.     secondary->config      = config;
  679.     secondary->info.config = config;
  680.     secondary->overlay_info.config = new->glxDraw.overlay_info.config;
  681.     InitializeOpenGLVisual(new, &secondary->info, &secondary->overlay_info );
  682. #endif /* USE_GL */
  683. }
  684.  
  685. /*------------------------------------------------------------------------
  686.  * Initialize
  687.  *    Called when widget is created (not mapped).  Sets up variables
  688.  *    needed and defaults for the resources.
  689.  *
  690.  * Resources set up:
  691.  *    core.width (100)
  692.  *    core.height (100)
  693.  *    core.colormap
  694.  *    glxDraw.visualInfo
  695.  *    core.depth
  696.  *    glxDraw.isRGB
  697.  *    glxDraw.{overlay_info & underlay_info & popup_info}.
  698.  *        colormap
  699.  *        visualInfo
  700.  *        depth
  701.  *   #ifdef __GLX_MOTIF
  702.  *    primitive.highlight_thickness
  703.  *    primitive.shadow_thickness
  704.  *   #endif
  705.  *
  706.  *        If both buffers are requested:
  707.  *    glxDraw.single_buffer (TRUE if current window is single buffered)
  708.  *    glxDraw.single_buffer_default (TRUE if default window was single)
  709.  *
  710.  *    glxDraw.sgl_buf.config
  711.  *    glxDraw.sgl_buf.info.colormap
  712.  *    glxDraw.sgl_buf.info.visualInfo
  713.  *    glxDraw.sgl_buf.info.depth
  714.  *
  715.  *    glxDraw.dbl_buf.config
  716.  *    glxDraw.dbl_buf.info.colormap
  717.  *    glxDraw.dbl_buf.info.visualInfo
  718.  *    glxDraw.dbl_buf.info.depth
  719.  *
  720.  *    glxDraw.cur_info
  721.  *    glxDraw.alt_colormap
  722.  *
  723.  * Variables set up:
  724.  *    isDouble (TRUE if default window is double buffered)
  725.  *    isStereo (TRUE if default window is stereo buffered)
  726.  *------------------------------------------------------------------------*/
  727.  
  728. static void Initialize (req, new)
  729.   GlxDrawWidget req, new;
  730. {
  731.     int            isDouble=FALSE;
  732.     int            isStereo=FALSE;
  733.     GlxDrawWindowInfo    normalWindowInfo;
  734.     GlxDrawWindowInfo    *curWindowInfo;
  735.     XVisualInfo        tmpl;
  736.     register        i;
  737.     int            nret;
  738. #ifdef USE_GL
  739.     GLXconfig        *newConfig;
  740. #else
  741.     int                 *newConfig;
  742. #endif
  743.     
  744. #ifdef DEBUG
  745.     XSynchronize(XtDisplay(new), True);
  746. #endif
  747.     
  748.     /*----
  749.      * Initialize core elements if they aren't already.
  750.      *----*/
  751.  
  752.     if (req->core.width == 0)
  753.     new->core.width = 100;
  754.     if (req->core.height == 0)
  755.     new->core.height = 100;
  756.     
  757.     /*----
  758.      * Initialize the normalWindowInfo structure.  This structure is used
  759.      * to collect all the information about the normal window before it
  760.      * is placed in the widget structure.
  761.      *----*/
  762.  
  763.     bzero (&normalWindowInfo, sizeof (normalWindowInfo));
  764.     normalWindowInfo.exists = TRUE;
  765.  
  766.     /*----
  767.      * By default, we want to override the colormap (we DON'T want to
  768.      * use the core colormap).  If the user has reqeusted that we DO
  769.      * want to use a colormap that he has provided, then do it here.
  770.      *----*/
  771.  
  772.     if (!new->glxDraw.override_colormap)
  773.     normalWindowInfo.colormap = new->core.colormap;
  774.  
  775.     
  776.     /*----
  777.      * Get the configuration information that matches what the user
  778.      * requested.
  779.      *
  780.      * If it fails, just return with an error saying that it isn't
  781.      * supported.
  782.      *----*/
  783.     
  784. #ifdef USE_GL
  785.     newConfig = GLXgetconfig (XtDisplay(new),
  786.                   XScreenNumberOfScreen(XtScreen(new)),
  787.                   new->glxDraw.config);
  788.     if (!newConfig)
  789.     {
  790.     error(new,"requested visual not supported");
  791.     return;
  792.     }
  793.  
  794.     new->glxDraw.config = newConfig;
  795. #else
  796. #endif /* USE_GL */
  797.     
  798.  
  799. #ifdef USE_GL
  800. /*------------------------------------------------------------------------ 
  801.  * Loop through all the entries in the new configuration structure.
  802.  * For each entry:
  803.  *    If there is a colormap entry in the configuration structure,
  804.  *      put it into the appropriate window info structure.
  805.  *    Get the visual info for each of the visuals requested and
  806.  *      provided and place it in the appropriate window info
  807.  *      structure.
  808.  *------------------------------------------------------------------------*/
  809.     
  810.     new->glxDraw.isRGB = FALSE;    /* Default is not RGB mode */
  811.     for (i=0; newConfig[i].buffer; i++)
  812.     {
  813.     switch (newConfig[i].buffer)
  814.     {
  815.       case GLX_NORMAL:
  816.         curWindowInfo = &normalWindowInfo;
  817.         break;
  818.       case GLX_OVERLAY:
  819.         curWindowInfo = &new->glxDraw.overlay_info;
  820.         break;
  821.       case GLX_UNDERLAY:
  822.         curWindowInfo = &new->glxDraw.underlay_info;
  823.         break;
  824.       case GLX_POPUP:
  825.         curWindowInfo = &new->glxDraw.popup_info;
  826.         break;
  827.     }
  828.     if (!curWindowInfo->exists)
  829.         continue;
  830.     switch (newConfig[i].mode)
  831.     {
  832.       case GLX_DOUBLE:
  833.         if ((newConfig[i].buffer == GLX_NORMAL) &&
  834.         new->glxDraw.provide_Sbuffer)
  835.         isDouble = newConfig[i].arg;
  836.         break;
  837.       case GLX_COLORMAP:
  838.         if (!curWindowInfo->colormap)
  839.         curWindowInfo->colormap = (Colormap)newConfig[i].arg;
  840.         break;
  841.       case GLX_VISUAL:
  842.         tmpl.visualid = newConfig[i].arg;
  843.         tmpl.screen = XScreenNumberOfScreen(XtScreen(new));
  844.         curWindowInfo->visualInfo =
  845.         XGetVisualInfo(XtDisplay(new),VisualScreenMask|VisualIDMask,
  846.                    &tmpl, &nret);
  847.         if (!curWindowInfo->visualInfo)
  848.         error (new,"Couldn't get visual");
  849.         curWindowInfo->depth = curWindowInfo->visualInfo->depth;
  850.         break;
  851.       case GLX_RGB:
  852.         if(newConfig[i].buffer == GLX_NORMAL)
  853.         new->glxDraw.isRGB = newConfig[i].arg;
  854.         break;
  855.     }
  856.     }
  857. #else
  858. /*------------------------------------------------------------------------ 
  859.  * Choose an OpenGL visual and create a colormap for it
  860.  *------------------------------------------------------------------------*/
  861.     normalWindowInfo.config = new->glxDraw.config;
  862.     InitializeOpenGLVisual(new, &normalWindowInfo, &new->glxDraw.overlay_info);
  863. #endif /* USE_GL */
  864.     
  865.     /*-----
  866.      * Save visual info for the normal window in the Core widget
  867.      *----*/
  868.     new->core.colormap      = normalWindowInfo.colormap;
  869.     new->glxDraw.visualInfo = normalWindowInfo.visualInfo;
  870.     new->core.depth         = normalWindowInfo.visualInfo->depth;
  871.  
  872. #ifdef DEBUG
  873. #if DEBUG & 0xFFFE
  874.     fprintf (stderr, "GlxDraw: Primary window is %s buffered.\n",
  875.          isDouble ? "double" : "single");
  876. #endif
  877. #if DEBUG & 0x0002
  878.     fprintf (stderr, "GlxDraw: Primary window colormap = 0x%08x\n",
  879.          new->core.colormap);
  880. #endif
  881. #if DEBUG & 0x0008
  882.     fprintf (stderr, "GlxDraw: Primary window visual ID = %d\n",
  883.          new->glxDraw.visualInfo->visualid);
  884.     fprintf (stderr, "         Depth of visual = %d\n",
  885.          new->glxDraw.visualInfo->depth);
  886.     fprintf (stderr, "         Colormap size = %d\n",
  887.          new->glxDraw.visualInfo->colormap_size);
  888. #endif
  889. #endif
  890.     
  891. #ifdef __GLX_MOTIF
  892.     /*---
  893.      * Clear any resources that shouldn't be changed by the user.
  894.      * The following resources cannot be changed by the user
  895.      *--*/
  896.  
  897.     new->primitive.highlight_thickness = 0;
  898.     new->primitive.shadow_thickness = 0;
  899.  
  900. #endif /* __GLX_MOTIF */
  901.  
  902. /*------------------------------------------------------------------------
  903.  * Here we do the work of making another window if the user requested
  904.  * both a double and single buffer capability.
  905.  *------------------------------------------------------------------------*/
  906.  
  907.     if (new->glxDraw.provide_Sbuffer || new->glxDraw.provide_StereoBuffer) {
  908. #ifdef USE_GL
  909.     GLXconfig    d_config[MAX_CONFIG], s_config[MAX_CONFIG];
  910.     GLXconfig    *tmpConfig;
  911.     int        di;
  912.     
  913.         /*----
  914.          * Create config structures that are identical to the one
  915.          * provided by the user except that one is single and the
  916.          * other is double.
  917.          *----*/
  918.  
  919.     di   = 0;
  920.     nret = 0;            /* Flag to say if GLX_DOUBLE found */
  921.     for (i = 0; req->glxDraw.config[i].buffer; i++)
  922.     {
  923.         tmpConfig    = &req->glxDraw.config[i];
  924.         d_config[di] = *tmpConfig;
  925.         s_config[di] = *tmpConfig;
  926.         if ((tmpConfig->buffer == GLX_NORMAL) &&
  927.         (tmpConfig->mode == GLX_DOUBLE))
  928.         {
  929.         s_config[di].arg = False;
  930.         d_config[di].arg = True;
  931.         nret = 1;
  932.         }
  933.         if (++di >= MAX_CONFIG)
  934.         {
  935.         error ((Widget)req, "GLXconfig to large to duplicate");
  936.         }
  937.     }
  938.     
  939.         /*----
  940.          * User didn't specify buffering in the config so
  941.          * forceably add entry to set GLX_DOUBLE for single and
  942.          * double buffering.  This should never happen.
  943.          *----*/
  944.  
  945.     if (!nret)
  946.     {
  947.         d_config[di].buffer = GLX_NORMAL;
  948.         d_config[di].mode   = GLX_DOUBLE;
  949.         d_config[di].arg    = True;
  950.         s_config[di].buffer    = GLX_NORMAL;
  951.         s_config[di].mode    = GLX_DOUBLE;
  952.         s_config[di].arg    = False;
  953.         di++;
  954.     }
  955.     d_config[di].buffer = s_config[di].buffer = 0;
  956. #else
  957.     int            d_config[MAX_CONFIG], s_config[MAX_CONFIG];
  958.         int             *attrPtr, *singlePtr, *doublePtr;
  959.  
  960.         attrPtr   = new->glxDraw.config;
  961.         singlePtr = s_config;
  962.         doublePtr = d_config;
  963.         while(attrPtr < &new->glxDraw.config[MAX_CONFIG])
  964.         {
  965.               switch(*attrPtr)
  966.               {
  967.               case GLX_DOUBLEBUFFER:
  968.                   *doublePtr = GLX_DOUBLEBUFFER;
  969.                   isDouble   = TRUE;
  970.                   /* Both buffers are double, one is mono, one is stereo */
  971.                   if(!new->glxDraw.provide_Sbuffer)
  972.                   {
  973.                       *singlePtr = GLX_DOUBLEBUFFER;
  974.                       singlePtr++;
  975.                   }
  976.                   attrPtr++; doublePtr++;
  977.                   break;
  978.               case GLX_STEREO:
  979.                   *doublePtr = GLX_STEREO;
  980.                   isStereo   = TRUE;
  981.                   /* Both buffers are stereo, one is single, one is double */
  982.                   if(!new->glxDraw.provide_StereoBuffer)
  983.                   {
  984.                       *singlePtr = GLX_STEREO;
  985.                       singlePtr++;
  986.                   }
  987.                   attrPtr++; doublePtr++;
  988.                   break;
  989.               case GLX_RGBA:
  990.                   new->glxDraw.isRGB = TRUE;
  991.                   *doublePtr = *attrPtr;
  992.                   *singlePtr = *attrPtr;
  993.                   attrPtr++; doublePtr++; singlePtr++;
  994.                   break;
  995.               case GLX_USE_GL:
  996.                   *doublePtr = *attrPtr;
  997.                   *singlePtr = *attrPtr;
  998.                   attrPtr++; doublePtr++; singlePtr++;
  999.                   break;
  1000.               case GLX_BUFFER_SIZE:
  1001.               case GLX_LEVEL:
  1002.               case GLX_AUX_BUFFERS:
  1003.               case GLX_RED_SIZE:
  1004.               case GLX_GREEN_SIZE:
  1005.               case GLX_BLUE_SIZE:
  1006.               case GLX_ALPHA_SIZE:
  1007.               case GLX_DEPTH_SIZE:
  1008.               case GLX_STENCIL_SIZE:
  1009.               case GLX_ACCUM_RED_SIZE:
  1010.               case GLX_ACCUM_GREEN_SIZE:
  1011.               case GLX_ACCUM_BLUE_SIZE:
  1012.               case GLX_ACCUM_ALPHA_SIZE:
  1013.                   *doublePtr = *attrPtr;
  1014.                   *singlePtr = *attrPtr;
  1015.                   attrPtr++; doublePtr++; singlePtr++;
  1016.                   *doublePtr = *attrPtr;
  1017.                   *singlePtr = *attrPtr;
  1018.                   attrPtr++; doublePtr++; singlePtr++;
  1019.                   break;
  1020.               case None:
  1021.                   if(!isDouble && new->glxDraw.provide_Sbuffer) 
  1022.                   {
  1023.                       *doublePtr = GLX_DOUBLEBUFFER; doublePtr++;
  1024.                   }
  1025.                   if(!isStereo && new->glxDraw.provide_StereoBuffer)
  1026.                   {
  1027.                       *doublePtr = GLX_STEREO; doublePtr++;
  1028.                   }
  1029.                   *doublePtr = *attrPtr;
  1030.                   *singlePtr = *attrPtr;
  1031.                   attrPtr = &new->glxDraw.config[MAX_CONFIG];
  1032.                   break;
  1033.               default:
  1034.                   error(new, "Invalid attribute in GLXConfig");
  1035.                   return;
  1036.               }
  1037.         }
  1038. #endif /*  USE_GL */
  1039.     
  1040.         /*----
  1041.          * Setup another window to allow switch to double buffering
  1042.          * Depending on which type of window has already been
  1043.          * requested, we request the other.
  1044.          *----*/
  1045.  
  1046.     if (!isDouble || !isStereo)        /* Default window was SINGLE BUFFERED */
  1047.     {
  1048.         new->glxDraw.single_buffer        = TRUE;
  1049.         new->glxDraw.single_buffer_default    = TRUE;
  1050.  
  1051.         /*----
  1052.          * Copy currently created window config and info to
  1053.          * single buffer structures
  1054.          *----*/
  1055.  
  1056.         new->glxDraw.sgl_buf.config = newConfig;
  1057.         memcpy(&new->glxDraw.sgl_buf.info, &normalWindowInfo,
  1058.            (size_t)sizeof(normalWindowInfo));
  1059.         new->glxDraw.cur_info = &new->glxDraw.sgl_buf.info;
  1060.  
  1061.         InitializeDup (new, &new->glxDraw.dbl_buf, d_config);
  1062.  
  1063.         new->glxDraw.alt_colormap = new->glxDraw.dbl_buf.info.colormap;
  1064. #ifdef DEBUG
  1065. #if DEBUG & 0x0008
  1066.         fprintf (stderr, "GlxDraw: Secondary window visual ID = %d\n",
  1067.              new->glxDraw.dbl_buf.info.visualInfo->visualid);
  1068.         fprintf (stderr, "         Depth of visual = %d\n",
  1069.              new->glxDraw.dbl_buf.info.visualInfo->depth);
  1070.         fprintf (stderr, "         Colormap size = %d\n",
  1071.              new->glxDraw.dbl_buf.info.visualInfo->colormap_size);
  1072. #endif
  1073. #endif
  1074.     }
  1075.  
  1076.         /*----
  1077.          * Setup another window to allow switch to single buffering
  1078.          * Default is double buffered
  1079.          *----*/
  1080.  
  1081.     else            /* Default window was DOUBLE BUFFERED */
  1082.     {
  1083.         new->glxDraw.single_buffer        = FALSE;
  1084.         new->glxDraw.single_buffer_default    = FALSE;
  1085.         
  1086.         /*----
  1087.          * Copy default window config and info to double
  1088.          * buffer structures
  1089.          *----*/
  1090.  
  1091.         new->glxDraw.dbl_buf.config = newConfig;
  1092.         memcpy(&new->glxDraw.dbl_buf.info, &normalWindowInfo,
  1093.            (size_t)sizeof(normalWindowInfo));
  1094.         new->glxDraw.cur_info = &new->glxDraw.dbl_buf.info;
  1095.         
  1096.         InitializeDup (new, &new->glxDraw.sgl_buf, s_config);
  1097.  
  1098.         new->glxDraw.alt_colormap = new->glxDraw.sgl_buf.info.colormap;
  1099. #ifdef DEBUG
  1100. #if DEBUG & 0x0008
  1101.         fprintf (stderr, "GlxDraw: Secondary window visual ID = %d\n",
  1102.              new->glxDraw.sgl_buf.info.visualInfo->visualid);
  1103.         fprintf (stderr, "         Depth of visual = %d\n",
  1104.              new->glxDraw.sgl_buf.info.visualInfo->depth);
  1105.         fprintf (stderr, "         Colormap size = %d\n",
  1106.              new->glxDraw.sgl_buf.info.visualInfo->colormap_size);
  1107. #endif
  1108. #endif
  1109.     }
  1110. #ifdef DEBUG
  1111. #if DEBUG & 0x0002
  1112.     fprintf (stderr, "GlxDraw: Secondary window colormap = 0x%08x\n",
  1113.          new->glxDraw.alt_colormap);
  1114. #endif
  1115. #endif
  1116.     }
  1117. }
  1118.  
  1119. /*------------------------------------------------------------------------
  1120.  * SetValuesAux
  1121.  *    Set values portion for the auxiliaries
  1122.  *------------------------------------------------------------------------*/
  1123.  
  1124. static void SetValuesAux (w, current, request, new)
  1125.   Widget w; /* for obtaining the display */
  1126.   GlxDrawWindowInfo *current, *request, *new;
  1127. {
  1128.     XSetWindowAttributes attributes;
  1129.  
  1130.     /* Changing the following after create time will harm me */
  1131.     new->exists = current->exists;
  1132.     new->window = current->window;
  1133.     new->depth = current->depth;
  1134.     new->visualInfo = current->visualInfo;
  1135.  
  1136. #ifdef DEBUG
  1137. #if DEBUG & 0x0004
  1138.     if (new->exists)
  1139.     fprintf (stderr, "GlxDraw: Changing values for window 0x%08x\n",
  1140.          new->window);
  1141. #endif
  1142. #if DEBUG & 0x0008
  1143.     if (new->exists)
  1144.     fprintf (stderr, "GlxDraw: Changing visual for window 0x%08x to %d\n",
  1145.          new->window, new->visualInfo->visualid);
  1146. #endif
  1147. #endif
  1148.  
  1149.     /* if the colormap has changed, and the window has been
  1150.      * created, change the colormap on the window */
  1151.     if (current->colormap != new->colormap && new->window)
  1152.     {
  1153.     attributes.colormap = new->colormap;
  1154.     XChangeWindowAttributes(
  1155.         XtDisplay(w), new->window, CWColormap, &attributes);
  1156. #ifdef DEBUG
  1157. #if DEBUG & 0x0002
  1158.     if (new->exists)
  1159.         fprintf(stderr,
  1160.             "GlxDraw: Changing colormap for window 0x%08x to 0x%08x\n",
  1161.             new->window, new->colormap);
  1162. #endif
  1163. #endif
  1164.     }
  1165. }
  1166.  
  1167.  
  1168. static void ResizeAux();
  1169.  
  1170. /*------------------------------------------------------------------------
  1171.  * SetNewWindow
  1172.  *------------------------------------------------------------------------*/
  1173.  
  1174. static void SetNewWindow(new, newBuffer, oldBuffer)
  1175.   GlxDrawWidget        new;
  1176.   GlxDrawBuffer        *newBuffer;
  1177.   GlxDrawBuffer        *oldBuffer;
  1178. {
  1179.     Window        root;
  1180.     int        x,y;
  1181.     unsigned int    width, height, border_width, depth;
  1182.  
  1183. #ifdef USE_GL
  1184.     Matrix        mSingle;
  1185.     Matrix        mProjection;
  1186.     Matrix        mViewing;
  1187.     Matrix        mTexture;
  1188.     long        mode;
  1189.  
  1190.     long        backFace;
  1191.     Boolean        cmMode;
  1192.     short        cposX, cposY;
  1193.     long        curColor;
  1194.     short        cursor;
  1195.     unsigned short    usdum;
  1196.     unsigned char    ucdum;
  1197.     long        ldum;
  1198.     Boolean        depthCue;
  1199.     long        drawMode;
  1200.     long        displayMode;
  1201.     long        fontNumber;
  1202.     Coord        curX, curY, curZ, curW;
  1203.     long        gethitcode;
  1204.     Boolean        lineSBackup;
  1205.     long        lineSRepeat;
  1206.     long        lineSReset;
  1207.     long        lineStyle;
  1208.     long        lineWidth;
  1209.     long        colorMap;
  1210.     long        pattern;
  1211.     Screencoord    left,right,top,bottom;
  1212.     long        shadingModel;
  1213.     long        writeMask;
  1214. #else
  1215.         GLfloat         modelViewMatrix[16];
  1216.         GLfloat         projectionMatrix[16];
  1217.         GLint           viewPort[4];
  1218.         GLfloat         modelViewMatrixOverlay[16];
  1219.         GLfloat         projectionMatrixOverlay[16];
  1220.         GLint           viewPortOverlay[4];
  1221. #endif /* USE_GL */
  1222.  
  1223.     new->glxDraw.cur_info       = &newBuffer->info;
  1224.     new->core.window       = newBuffer->info.window; 
  1225. #ifndef USE_GL
  1226.     new->glxDraw.context       = newBuffer->info.context; 
  1227. #endif
  1228.     new->glxDraw.visualInfo    = newBuffer->info.visualInfo;
  1229.     new->glxDraw.overlay_info  = newBuffer->overlay_info;
  1230.     new->glxDraw.underlay_info = newBuffer->underlay_info;
  1231.     new->glxDraw.popup_info    = newBuffer->popup_info;
  1232.  
  1233.  
  1234. /* Get all possible attributes from old window */
  1235. #ifdef USE_GL
  1236.     mode    = getmmode();
  1237.     if(mode == MSINGLE)
  1238.     {
  1239.         mmode(MSINGLE);
  1240.         getmatrix(mSingle);
  1241.     }else{
  1242.         mmode(MPROJECTION);
  1243.         getmatrix(mProjection);
  1244.         mmode(MVIEWING);
  1245.         getmatrix(mViewing);
  1246.         mmode(MTEXTURE);
  1247.         getmatrix(mTexture);
  1248.         mmode(mode);
  1249.     }
  1250.  
  1251.     displayMode    = getdisplaymode();
  1252.  
  1253.     backFace    = getbackface();
  1254.         if(displayMode == DMSINGLE || displayMode == DMDOUBLE)
  1255.     {
  1256.         cmMode        = getcmmode();
  1257.         curColor    = getcolor();
  1258.         colorMap    = getmap();
  1259.     }
  1260.     getcursor (&cursor, &usdum, &usdum, &ldum);
  1261. /*    getcpos (&cposX, &cposY);*/
  1262.     depthCue    = getdcm();
  1263. /*    drawMode     = getdrawmode();*/
  1264.     fontNumber     = getfont();
  1265. /*    getgpos (&curX, &curY, &curZ, &curW);*/
  1266. /*    hitCode        = gethitcode;*/
  1267.     lineSBackup    = getlsbackup();
  1268.     lineSRepeat    = getlsrepeat();
  1269. /*    lineSReset    = getresetls();*/
  1270.     lineStyle    = getlstyle();
  1271. /*    lineWidth    = getlwidth();*/
  1272.     pattern        = getpattern();
  1273.     getscrmask(&left, &right, &bottom, &top);
  1274.     shadingModel    = getsm();
  1275.     writeMask    = getwritemask();
  1276. #else
  1277.         glXMakeCurrent(XtDisplay (new), oldBuffer->info.window,
  1278.                         oldBuffer->info.context);
  1279.         glGetFloatv(GL_MODELVIEW_MATRIX,  modelViewMatrix);
  1280.         glGetFloatv(GL_PROJECTION_MATRIX, projectionMatrix);
  1281.         glGetIntegerv(GL_VIEWPORT,        viewPort);
  1282.         if(oldBuffer->overlay_info.exists)
  1283.         {
  1284.             glXMakeCurrent(XtDisplay (new), oldBuffer->overlay_info.window,
  1285.                         oldBuffer->overlay_info.context);
  1286.             glGetFloatv(GL_MODELVIEW_MATRIX,  modelViewMatrixOverlay);
  1287.             glGetFloatv(GL_PROJECTION_MATRIX, projectionMatrixOverlay);
  1288.             glGetIntegerv(GL_VIEWPORT,        viewPortOverlay);
  1289.         }
  1290. #endif /* USE_GL */
  1291.  
  1292. /* Get geometry of old window, then resize the new one to match */
  1293.     if(!XGetGeometry(XtDisplay (new), oldBuffer->info.window,
  1294.              &root, &x, &y, &width, &height,
  1295.              &border_width, &depth))
  1296.         warning ((Widget)new, "SetNewWindow : XGetGeometry failed");
  1297.  
  1298. /* Map new window for X */
  1299.     XMapRaised (XtDisplay (new), newBuffer->info.window);
  1300.  
  1301. #ifdef DEBUG
  1302. #if DEBUG & 0x0004
  1303.     fprintf (stderr, "GlxDraw: Changing GLX window to 0x%08x\n",
  1304.          newBuffer->info.window);
  1305. #endif
  1306. #endif
  1307.  
  1308. /* Set new window for GL */
  1309. #ifdef USE_GL
  1310.     GLXwinset  (XtDisplay (new), newBuffer->info.window);
  1311.  
  1312.     XResizeWindow(XtDisplay (new), newBuffer->info.window,
  1313.             width, height);
  1314.  
  1315.     viewport(0, (Screencoord) width-1, 0, (Screencoord) height-1);
  1316.  
  1317.     ResizeAux(new,    &newBuffer->overlay_info,
  1318.             &newBuffer->underlay_info,
  1319.             &newBuffer->popup_info);
  1320. /* What kind of display mode am i really in */
  1321.     displayMode    = getdisplaymode();
  1322.  
  1323. /* Set old windows attributes on the new window */
  1324.     if(mode == MSINGLE)
  1325.     { 
  1326.         mmode(MSINGLE);
  1327.         loadmatrix(mSingle);
  1328.     }else{
  1329.             mmode(MPROJECTION);
  1330.             loadmatrix(mProjection);
  1331.             mmode(MVIEWING);
  1332.             loadmatrix(mViewing);
  1333.             mmode(MTEXTURE);
  1334.             loadmatrix(mTexture);
  1335.     }
  1336.     mmode(mode);
  1337.  
  1338.     backface(backFace);
  1339.     setcursor(cursor, usdum, usdum);
  1340.     if(displayMode == DMSINGLE || displayMode == DMDOUBLE)
  1341.     {
  1342.         color(curColor);
  1343.         if(cmMode)
  1344.             onemap();
  1345.         else{
  1346.             multimap();
  1347.             setmap(colorMap);
  1348.         }
  1349.     }
  1350.     depthcue(depthCue);
  1351.     font(fontNumber);
  1352.     lsbackup(lineSBackup);
  1353.     lsrepeat(lineSRepeat);
  1354.     setpattern(pattern);
  1355.     shademodel(shadingModel);
  1356. #else
  1357. /*
  1358.  * Make the new overlay window like the old one where possible if there is one
  1359.  */
  1360.         if(newBuffer->overlay_info.exists)
  1361.         {
  1362.             glXMakeCurrent(XtDisplay (new), newBuffer->overlay_info.window,
  1363.                         newBuffer->overlay_info.context);
  1364.  
  1365.             glViewport(viewPortOverlay[0], viewPortOverlay[1],
  1366.                         viewPortOverlay[2], viewPortOverlay[3]);
  1367.  
  1368.         ResizeAux(new, &newBuffer->overlay_info,
  1369.             &newBuffer->underlay_info,
  1370.             &newBuffer->popup_info);
  1371.  
  1372.             glMatrixMode(GL_PROJECTION);
  1373.               glLoadMatrixf(projectionMatrix);
  1374.             glMatrixMode(GL_MODELVIEW);
  1375.               glLoadMatrixf(modelViewMatrix);
  1376.         }
  1377. /*
  1378.  * Make the new normal window like the old one where possible
  1379.  */
  1380.         glXMakeCurrent(XtDisplay (new), newBuffer->info.window,
  1381.                         newBuffer->info.context);
  1382.  
  1383.     XResizeWindow(XtDisplay (new), newBuffer->info.window,
  1384.             width, height);
  1385.  
  1386.         glViewport(viewPort[0], viewPort[1], viewPort[2], viewPort[3]);
  1387.  
  1388.         glMatrixMode(GL_PROJECTION);
  1389.           glLoadMatrixf(projectionMatrix);
  1390.         glMatrixMode(GL_MODELVIEW);
  1391.           glLoadMatrixf(modelViewMatrix);
  1392. #endif /* USE_GL */
  1393. }
  1394.  
  1395. /*------------------------------------------------------------------------
  1396.  * SetAux        Handle requests to change resources in aux windows.
  1397.  *------------------------------------------------------------------------*/
  1398. static void SetAux (current, request, new)
  1399.   GlxDrawWidget current, request, new; 
  1400. {
  1401.     SetValuesAux(new,
  1402.          ¤t->glxDraw.overlay_info,
  1403.          &request->glxDraw.overlay_info,
  1404.          &new->glxDraw.overlay_info);
  1405.     SetValuesAux(new,
  1406.          ¤t->glxDraw.underlay_info,
  1407.          &request->glxDraw.underlay_info,
  1408.          &new->glxDraw.underlay_info);
  1409.     SetValuesAux(new,
  1410.          ¤t->glxDraw.popup_info,
  1411.          &request->glxDraw.popup_info,
  1412.          &new->glxDraw.popup_info);
  1413. }
  1414.  
  1415.  
  1416. /*------------------------------------------------------------------------
  1417.  * SetValues        Handle requests to change resources.
  1418.  *
  1419.  * Returns:
  1420.  *    True    Xlib must call XClearArea and the <expose> callbacks.
  1421.  *    False    No redrawing is required.
  1422.  *------------------------------------------------------------------------*/
  1423. static Boolean SetValues (current, request, new)
  1424.   GlxDrawWidget current, request, new;
  1425. {
  1426.     SetAux(current, request, new);
  1427.  
  1428. #ifdef __GLX_MOTIF
  1429.     /* The following resources cannot be changed by the user */
  1430.     new->primitive.highlight_thickness = 0;
  1431.     new->primitive.shadow_thickness = 0;
  1432. #endif            /* __GLX_MOTIF */
  1433.  
  1434. /*----
  1435.  * If setting to single buffer mode from double buffer mode.
  1436.  *----*/
  1437.     if (new->glxDraw.single_buffer) {
  1438.         if (!current->glxDraw.single_buffer) {
  1439.       if(current->glxDraw.single_buffer_default)
  1440.             XUnmapWindow(XtDisplay(new), current->glxDraw.dbl_buf.info.window);
  1441.       SetNewWindow(new, &new->glxDraw.sgl_buf, &new->glxDraw.dbl_buf);
  1442.           return(True);    /* Force an expose/redraw */
  1443.         }
  1444.  
  1445. /*----
  1446.  * If setting to double buffer mode from single buffer mode.
  1447.  *----*/
  1448.     } else if (current->glxDraw.single_buffer) {
  1449.       if(!current->glxDraw.single_buffer_default)
  1450.     XUnmapWindow (XtDisplay(new), current->glxDraw.sgl_buf.info.window);
  1451.       SetNewWindow(new, &new->glxDraw.dbl_buf, &new->glxDraw.sgl_buf);
  1452. #ifndef USE_GL
  1453.       glDrawBuffer(GL_BACK);
  1454. #endif
  1455.       return(True);    /* Force an expose/redraw */
  1456.     }
  1457.     return (False);    /* No expose/redraw */
  1458. }
  1459.  
  1460. /*------------------------------------------------------------------------
  1461.  * RealizeAux
  1462.  *    Called to create overlay, underlay and/or popup windows.
  1463.  *
  1464.  * Resources set up:
  1465.  *    glxDraw.overlay_info.window
  1466.  *    glxDraw.underlay_info.window
  1467.  *    glxDraw.popup_info.window
  1468.  *------------------------------------------------------------------------*/
  1469.  
  1470. static void RealizeAux (glw, aux_info, parent)
  1471.   register GlxDrawWidget    glw;
  1472.   register GlxDrawWindowInfo    *aux_info;
  1473.   Window            parent;
  1474. {
  1475.     XSetWindowAttributes aux_attributes;
  1476.     
  1477.     aux_attributes.colormap = aux_info->colormap;
  1478.     aux_attributes.border_pixel = 0;
  1479.     aux_info->window =
  1480.     XCreateWindow(XtDisplay(glw), parent, 0, 0,
  1481.               glw->core.width, glw->core.height, 0,
  1482.               aux_info->depth, InputOutput,
  1483.               aux_info->visualInfo->visual,
  1484.               CWColormap|CWBorderPixel, &aux_attributes);
  1485.     XMapWindow(XtDisplay(glw),aux_info->window);
  1486.  
  1487.     /*
  1488.      * We explicitly need the exposure events for this window
  1489.      */
  1490.  
  1491.     XSelectInput(XtDisplay(glw), aux_info->window,    ExposureMask);
  1492.  
  1493.     /* Tell Xt to tell us about the exposure events
  1494.      * Note that this is a private Xt routine that may change in the
  1495.      * future, but it is the only way to get the exposure events.  This
  1496.      * code may need to change in the future
  1497.      */
  1498.  
  1499.     _XtRegisterWindow(aux_info->window,glw);
  1500.  
  1501. #ifdef DEBUG
  1502. #if DEBUG & 0x0004
  1503.     fprintf (stderr, "         Window created = 0x%08x\n", aux_info->window);
  1504. #endif
  1505. #endif
  1506. }
  1507.  
  1508. /*------------------------------------------------------------------------
  1509.  * RealizeDup
  1510.  *    Duplicate of Realize except for secondary window.
  1511.  *------------------------------------------------------------------------*/
  1512.  
  1513. static int RealizeDup(glw, primary, secondary, valueMask, attributes)
  1514.   GlxDrawWidget          glw;
  1515.   GlxDrawBuffer        *primary;
  1516.   GlxDrawBuffer        *secondary;
  1517.   Mask            *valueMask;
  1518.   XSetWindowAttributes    *attributes;
  1519. {
  1520.     GlxDrawWindowInfo    *info;
  1521. #ifdef USE_GL
  1522.     register GLXconfig    *glp;
  1523. #else
  1524. #endif /* USE_GL */
  1525.     Window        windows[2];
  1526.     int            cmapAlloc;
  1527.     int            has_aux=FALSE;
  1528.     int            i;
  1529.     int            stat;
  1530.  
  1531.     glw->glxDraw.mainWindow = primary->info.window;
  1532.  
  1533.     info = &secondary->info;
  1534.     /*
  1535.      * You must allocate and set a new colormap if the secondary window
  1536.      *    visual doesn't match the primary (Usually the case when
  1537.      *    using this feature, sincde depth in single is greater than double)
  1538.      *
  1539.      * Note the secondary window depth must always be less than the parent
  1540.      *
  1541.      */
  1542.     if(glw->glxDraw.visualInfo->depth != info->depth)
  1543.     {
  1544.     if(glw->glxDraw.visualInfo->depth < info->depth)
  1545.     {
  1546.         error ((Widget)glw,
  1547.            "Fatal error: Child depth greater than parent\n");
  1548.     }
  1549.     }
  1550.     /*
  1551.      * Create an X window for secondary buffer.  Not mapped yet.  It will be
  1552.      * rolled in when appropriate set values is done.
  1553.      */
  1554.     
  1555.     attributes->colormap = info->colormap;
  1556.     *valueMask |= CWColormap;
  1557.     info->window = XCreateWindow (XtDisplay(glw),
  1558.                   XtWindow(glw),
  1559.                   0, 0,
  1560.                   glw->core.width, glw->core.height, 0,
  1561.                   info->depth, InputOutput,
  1562.                   info->visualInfo->visual,
  1563.                   *valueMask, attributes);
  1564.     
  1565. #ifdef ORIGINAL
  1566.     /* this is not needed, and breaks input on 5.1 */
  1567.     XSelectInput (XtDisplay (glw), info->window, ExposureMask);
  1568. #endif
  1569.     _XtRegisterWindow (info->window, glw);
  1570.  
  1571. #ifdef DEBUG
  1572. #if DEBUG & 0x0004
  1573.     fprintf (stderr, "GlxDraw: Secondary window is 0x%08x\n", info->window);
  1574. #endif
  1575. #endif
  1576.  
  1577.     /*
  1578.      * Special case for Indigo Starter which uses a PsuedoColor visual
  1579.      *    for RGB mode.  Requires building my own color map
  1580.      *
  1581.      * Tell window manager I have a special color map
  1582.      */
  1583.     if(glw->glxDraw.isRGB
  1584.        && info->visualInfo->class == PseudoColor)
  1585.     {
  1586.     windows[0] = info->window;
  1587.     stat = XSetWMColormapWindows(XtDisplay(glw),
  1588.                      XtWindow(glw),
  1589.                      windows,
  1590.                      1);
  1591.     if(!stat)
  1592.         warning ((Widget)glw, "XSetWMColormapWindows failed\n");
  1593.     }
  1594.  
  1595.     /*
  1596.      * Copy default auxiliary info to structures for primary and
  1597.      * secondary buffers
  1598.      */
  1599.     primary->overlay_info    = glw->glxDraw.overlay_info;
  1600.     primary->underlay_info    = glw->glxDraw.underlay_info;
  1601.     primary->popup_info        = glw->glxDraw.popup_info;
  1602. #ifndef USE_GL
  1603.     primary->info.context       = glw->glxDraw.context;
  1604. #endif
  1605.     
  1606.     secondary->overlay_info    = glw->glxDraw.overlay_info;
  1607.     secondary->underlay_info    = glw->glxDraw.underlay_info;
  1608.     secondary->popup_info    = glw->glxDraw.popup_info;
  1609.     
  1610.     /*
  1611.      * Duplicate auxiliary windows, if necessary, for secondary buffer
  1612.      */
  1613.     if (glw->glxDraw.overlay_info.exists) {
  1614.     has_aux = TRUE;
  1615. #ifdef DEBUG
  1616. #if DEBUG & 0x0004
  1617.     fprintf (stderr, "GlxDraw: Creating secondary overlay window\n");
  1618. #endif
  1619. #endif
  1620.     RealizeAux (glw,&secondary->overlay_info, info->window);
  1621.     }
  1622.     if (glw->glxDraw.underlay_info.exists) {
  1623.     has_aux = TRUE;
  1624. #ifdef DEBUG
  1625. #if DEBUG & 0x0004
  1626.     fprintf (stderr, "GlxDraw: Creating secondary underlay window\n");
  1627. #endif
  1628. #endif
  1629.     RealizeAux (glw,&secondary->underlay_info, info->window);
  1630.     }
  1631.     if (glw->glxDraw.popup_info.exists) {
  1632.     has_aux = TRUE;
  1633. #ifdef DEBUG
  1634. #if DEBUG & 0x0004
  1635.     fprintf (stderr, "GlxDraw: Creating secondary popup window\n");
  1636. #endif
  1637. #endif
  1638.     RealizeAux (glw,&secondary->popup_info, info->window);
  1639.     }
  1640.     
  1641. #ifdef USE_GL
  1642.     /*
  1643.      * Store windows in appropriate places in config structure for GLXlink
  1644.      */
  1645.     for (glp = secondary->config; glp->buffer; glp++) {
  1646.     if (glp->mode == GLX_WINDOW) {
  1647.             switch (glp->buffer) {
  1648.               case GLX_NORMAL:
  1649.                 glp->arg = info->window;
  1650.                 break;
  1651.               case GLX_OVERLAY:
  1652.                 if (secondary->overlay_info.exists)
  1653.                     glp->arg = secondary->overlay_info.window;
  1654.                 break;
  1655.               case GLX_UNDERLAY:
  1656.                 if (secondary->underlay_info.exists)
  1657.                     glp->arg = secondary->underlay_info.window;
  1658.                 break;
  1659.               case GLX_POPUP:
  1660.                 if (secondary->popup_info.exists)
  1661.                     glp->arg = secondary->popup_info.window;
  1662.                 break;
  1663.             }
  1664.     }
  1665.     }
  1666.     
  1667.     
  1668.     
  1669.     /* Link the secondary window for GL */
  1670.     i = GLXlink (XtDisplay (glw), secondary->config);
  1671.     if (i < 0)
  1672.     error (glw, gl_errs[-i]);
  1673. #else
  1674. /* Create an OpenGL context on the X window */
  1675.     info->context = glXCreateContext(XtDisplay(glw),
  1676.                                       info->visualInfo, 0, GL_TRUE);
  1677.     if(!info->context){
  1678.         error("OpenGL not supported on this display");
  1679.         return;
  1680.     }
  1681.  
  1682.     if(secondary->overlay_info.exists)
  1683.     {
  1684.         secondary->overlay_info.context = glXCreateContext(XtDisplay(glw),
  1685.                                       secondary->overlay_info.visualInfo,
  1686.                                       0, GL_TRUE);
  1687.         if(!secondary->overlay_info.context){
  1688.             error("OpenGL overlay not supported on this display");
  1689.             return;
  1690.         }
  1691.     }
  1692. #endif /* USE_GL */
  1693.     
  1694.     
  1695.     glw->glxDraw.visualInfo = primary->info.visualInfo;
  1696.     
  1697.     return(has_aux);
  1698. }
  1699.  
  1700. /*------------------------------------------------------------------------
  1701.  * Realize
  1702.  *    Called when widget is to be mapped.  Does final loading of
  1703.  *    resources.  Maps all subwindows (overlay, underlay and popup).
  1704.  *
  1705.  * Resources set up:
  1706.  *    glxDraw.config [GLX_NORMAL & GLX_WINDOW]
  1707.  *    glxDraw.config [GLX_OVERLAY & GLX_WINDOW]
  1708.  *    glxDraw.config [GLX_UNDERLAY & GLX_WINDOW]
  1709.  *    glxDraw.config [GLX_POPUP & GLX_WINDOW]
  1710.  *    glxDraw.mainWindow
  1711.  *    glxDraw.cur_info->window
  1712.  *------------------------------------------------------------------------*/
  1713.  
  1714. static void Realize(w, valueMask, attributes)
  1715.   Widget w;
  1716.   Mask *valueMask;
  1717.   XSetWindowAttributes *attributes;
  1718. {
  1719.     register GlxDrawWidget    glw = (GlxDrawWidget)w;
  1720.     Boolean            has_aux=FALSE;
  1721.     GlxDrawCallbackStruct    cb;
  1722. #ifdef USE_GL
  1723.     register GLXconfig        *glp;
  1724. #endif /* USE_GL */
  1725.     XColor            colorDefs[256];
  1726.     int                i;
  1727.  
  1728. /* Since GL programs are expected to clear the screen themselves,
  1729.  * we don't want X to clear the screen, so don't set the background
  1730.  * pixel.
  1731.  */
  1732.     *valueMask &= ~CWBackPixel;
  1733.  
  1734.     XtCreateWindow (w, (unsigned int)InputOutput,
  1735.             glw->glxDraw.visualInfo->visual,
  1736.             *valueMask, attributes);
  1737.  
  1738. #ifdef DEBUG
  1739. #if DEBUG & 0x0004
  1740.     fprintf (stderr, "GlxDraw: Primary window is 0x%08x\n", XtWindow (glw));
  1741. #endif
  1742. #endif
  1743.  
  1744.     if (glw->glxDraw.overlay_info.exists) {
  1745.     has_aux = TRUE;
  1746. #ifdef DEBUG
  1747. #if DEBUG & 0x0004
  1748.     fprintf (stderr, "GlxDraw: Creating primary overlay window\n");
  1749. #endif
  1750. #endif
  1751.     RealizeAux (glw,&glw->glxDraw.overlay_info, XtWindow (glw));
  1752.     }
  1753.     if (glw->glxDraw.underlay_info.exists) {
  1754.     has_aux = TRUE;
  1755. #ifdef DEBUG
  1756. #if DEBUG & 0x0004
  1757.     fprintf (stderr, "GlxDraw: Creating primary underlay window\n");
  1758. #endif
  1759. #endif
  1760.     RealizeAux (glw,&glw->glxDraw.underlay_info, XtWindow (glw));
  1761.     }
  1762.     if (glw->glxDraw.popup_info.exists) {
  1763.     has_aux = TRUE;
  1764. #ifdef DEBUG
  1765. #if DEBUG & 0x0004
  1766.     fprintf (stderr, "GlxDraw: Creating primary popup window\n");
  1767. #endif
  1768. #endif
  1769.     RealizeAux (glw,&glw->glxDraw.popup_info, XtWindow (glw));
  1770.     }
  1771.  
  1772.     /*----
  1773.      * Now go through all the GLXconfig structures and fill
  1774.      * in the GLX_WINDOW argument for each type of window.
  1775.      *----*/
  1776.  
  1777. #ifdef USE_GL
  1778.     for (glp = glw->glxDraw.config; glp->buffer; glp++) {
  1779.     if (glp->mode == GLX_WINDOW) {
  1780.         switch (glp->buffer) {
  1781.           case GLX_NORMAL:
  1782.         glp->arg = XtWindow(glw);
  1783.         glw->glxDraw.mainWindow = XtWindow (glw);
  1784.         break;
  1785.           case GLX_OVERLAY:
  1786.         if (glw->glxDraw.overlay_info.exists)
  1787.             glp->arg = glw->glxDraw.overlay_info.window;
  1788.         break;
  1789.           case GLX_UNDERLAY:
  1790.         if (glw->glxDraw.underlay_info.exists)
  1791.             glp->arg = glw->glxDraw.underlay_info.window;
  1792.         break;
  1793.           case GLX_POPUP:
  1794.         if (glw->glxDraw.popup_info.exists)
  1795.             glp->arg = glw->glxDraw.popup_info.window;
  1796.         break;
  1797.         }
  1798.     }
  1799.     }
  1800.  
  1801.     i = GLXlink(XtDisplay(w), glw->glxDraw.config);
  1802.     if (i < 0)
  1803.     error (glw, gl_errs[-i]);
  1804. #else
  1805. /* Create an OpenGL context on the X window */
  1806.     glw->glxDraw.context = glXCreateContext(XtDisplay(w),
  1807.                                       glw->glxDraw.visualInfo, 0, GL_TRUE);
  1808.     if(!glw->glxDraw.context){
  1809.         error("OpenGL not supported on this display");
  1810.         return;
  1811.     }
  1812.  
  1813. /* Make the OpenGL context we just created the current one */
  1814.     if (!glXMakeCurrent(XtDisplay(w), XtWindow(w), glw->glxDraw.context)) {
  1815.         error("Can't make window current to OpenGL context\n");
  1816.         return;
  1817.     }
  1818.  
  1819.     if (glw->glxDraw.overlay_info.exists)
  1820.     {
  1821.         glw->glxDraw.overlay_info.context = glXCreateContext(XtDisplay(w),
  1822.                                       glw->glxDraw.overlay_info.visualInfo,
  1823.                                       0, GL_TRUE);
  1824.         if(!glw->glxDraw.overlay_info.context){
  1825.             error("OpenGL overlay not supported on this display");
  1826.             return;
  1827.         }
  1828.     }
  1829. #endif /* USE_GL */
  1830.  
  1831. /*
  1832.  * If provide_Sbuffer is set then allow switching between single and double
  1833.  * buffering.  Requires creation of a secondary window which is used
  1834.  * for alternate mode.  If main window is double buffered then secondary
  1835.  * window is single buffered and vice versa.
  1836.  *
  1837.  * Underlay, overlay and popups are also duplicated with secondary window
  1838.  * as the parent
  1839.  */
  1840.  
  1841.     if (glw->glxDraw.provide_Sbuffer || glw->glxDraw.provide_StereoBuffer) {
  1842.     GlxDrawWindowInfo    *curWindowInfo;
  1843.     int            i;
  1844. /*
  1845.  * Set window for the default window in current info structure
  1846.  */
  1847.  
  1848.     glw->glxDraw.cur_info->window = XtWindow (glw);
  1849.  
  1850.  
  1851. /*
  1852.  * Make auxiliary window to allow switch to double buffering 
  1853.  */
  1854.     if(glw->glxDraw.single_buffer_default)
  1855.     {
  1856.         RealizeDup(glw, &glw->glxDraw.sgl_buf.info,
  1857.                 &glw->glxDraw.dbl_buf.info,
  1858.                 valueMask,
  1859.                 attributes);
  1860. /*
  1861.  * or else make auxiliary window to allow switch to single buffering 
  1862.  */
  1863.     }
  1864.     else
  1865.     {
  1866.         RealizeDup(glw, &glw->glxDraw.dbl_buf.info,
  1867.                 &glw->glxDraw.sgl_buf.info,
  1868.                 valueMask,
  1869.                 attributes);
  1870.     }
  1871.     }
  1872.     /* Be a nice guy and do one GLXwinset on the main window.  This avoids
  1873.      * the need to do GLXwinsets in programs with only one window.
  1874.      */
  1875.  
  1876. #ifdef USE_GL
  1877.     GLXwinset(XtDisplay(w), XtWindow(w));
  1878.  
  1879.     if(glw->glxDraw.isRGB)
  1880.     cpack(0);
  1881.     else
  1882.     color(0);
  1883.     clear();
  1884. #else
  1885.     glXMakeCurrent(XtDisplay (w), XtWindow(w), glw->glxDraw.context);
  1886. #endif /* USE_GL */
  1887.  
  1888.     /* If there is an overlay or an underlay, we need to be notified if it
  1889.      * is destroyed */
  1890.     if (has_aux)
  1891.     XtAddEventHandler((Widget) glw, SubstructureNotifyMask, FALSE,
  1892.               auxwindow_destroyed, NULL);
  1893.  
  1894.     cb.reason    = GlxCR_GINIT;
  1895.     cb.event    = NULL;
  1896.     cb.window    = XtWindow(glw);
  1897.     cb.width    = glw->core.width;
  1898.     cb.height    = glw->core.height;
  1899. #ifndef USE_GL
  1900.     cb.context  = glw->glxDraw.context;
  1901. #endif
  1902.     XtCallCallbackList((Widget) glw, glw->glxDraw.ginit_callback, &cb);
  1903. }
  1904.  
  1905. /*------------------------------------------------------------------------
  1906.  * Redraw
  1907.  *------------------------------------------------------------------------*/
  1908.  
  1909. static void Redraw (glw, event, region)
  1910.   GlxDrawWidget    glw;
  1911.   XEvent    *event;
  1912.   Region    region;
  1913. {
  1914.    GlxDrawCallbackStruct cb;
  1915.    XtCallbackList cblist;
  1916.    
  1917.    cb.reason = GlxCR_EXPOSE;
  1918.    cb.event  = event;
  1919.    cb.window = event->xexpose.window;
  1920.    cb.width  = glw->core.width;
  1921.    cb.height = glw->core.height;
  1922.    if (cb.window == XtWindow(glw))
  1923.    {
  1924. #ifdef USE_GL
  1925.        cb.buffer  = GLX_NORMAL;
  1926. #else
  1927.        cb.context = glw->glxDraw.context;
  1928. #endif /* USE_GL */
  1929.        cblist = glw->glxDraw.expose_callback;
  1930.    }
  1931.    else if (cb.window == glw->glxDraw.dbl_buf.info.window) {
  1932. #ifdef USE_GL
  1933.        cb.buffer = GLX_NORMAL;
  1934. #else
  1935.        cb.context =  glw->glxDraw.dbl_buf.info.context;
  1936. #endif /* USE_GL */
  1937.        cblist = glw->glxDraw.expose_callback;
  1938.    }
  1939.    else if (cb.window == glw->glxDraw.sgl_buf.info.window) {
  1940. #ifdef USE_GL
  1941.        cb.buffer = GLX_NORMAL;
  1942. #else
  1943.        cb.context =  glw->glxDraw.sgl_buf.info.context;
  1944. #endif /* USE_GL */
  1945.        cblist = glw->glxDraw.expose_callback;
  1946.    }
  1947.    else if (cb.window == glw->glxDraw.overlay_info.window)
  1948.    {
  1949. #ifdef USE_GL
  1950.        cb.buffer = GLX_OVERLAY;
  1951. #else
  1952.        cb.context = glw->glxDraw.overlay_info.context;
  1953. #endif /* USE_GL */
  1954.        cblist = glw->glxDraw.overlay_info.expose_callback;
  1955.    }
  1956.    else if (cb.window == glw->glxDraw.underlay_info.window)
  1957.    {
  1958. #ifdef USE_GL
  1959.        cb.buffer = GLX_UNDERLAY;
  1960. #else
  1961.        cblist = glw->glxDraw.underlay_info.expose_callback;
  1962. #endif /* USE_GL */
  1963.        cblist = glw->glxDraw.underlay_info.expose_callback;
  1964.    }
  1965.    else if (cb.window == glw->glxDraw.popup_info.window)
  1966.    {
  1967. #ifdef USE_GL
  1968.        cb.buffer = GLX_POPUP;
  1969. #else
  1970.        cblist = glw->glxDraw.popup_info.expose_callback;
  1971. #endif /* USE_GL */
  1972.        cblist = glw->glxDraw.popup_info.expose_callback;
  1973.    }
  1974.    else
  1975.    {
  1976. /*
  1977.  *  Probably a redraw on an inactive secondary window
  1978.  *  Usually from resize, since we have to have resize events to all windows
  1979.  *  but we don't want redraw on inactive windows 
  1980.  */
  1981.     return;
  1982.    }
  1983.    XtCallCallbackList ((Widget) glw, cblist, &cb);
  1984. }
  1985.  
  1986. /*------------------------------------------------------------------------
  1987.  * ResizeCallback
  1988.  *------------------------------------------------------------------------*/
  1989.  
  1990. static void ResizeCallback(glw, window)
  1991.   GlxDrawWidget    glw;
  1992.   Window        window;
  1993. {
  1994.     GlxDrawCallbackStruct cb;
  1995.  
  1996.     cb.reason    = GlxCR_RESIZE;
  1997.     cb.event    = NULL;
  1998.     cb.window    = window;
  1999.     cb.width    = glw->core.width;
  2000.     cb.height    = glw->core.height;
  2001. #ifdef USE_GL
  2002.     cb.buffer    = GLX_NORMAL;
  2003. #else
  2004.     cb.context  = glw->glxDraw.context;
  2005. #endif /* USE_GL */
  2006.     /* The following XSync fixes a bug whereby viewport can fail.
  2007.     * On Indigo, viewport queries the size of the X window
  2008.     * and gets the old size without this Xsync.
  2009.     */
  2010.     XSync(XtDisplay(glw),FALSE);
  2011.     XtCallCallbackList ((Widget) glw, glw->glxDraw.resize_callback, &cb);
  2012. }
  2013.  
  2014. /*------------------------------------------------------------------------
  2015.  * ResizeAux
  2016.  *------------------------------------------------------------------------*/
  2017.  
  2018. static void ResizeAux(glw, overlay_info, underlay_info, popup_info)
  2019.   GlxDrawWidget        glw;
  2020.   GlxDrawWindowInfo    *overlay_info, *underlay_info, *popup_info;
  2021. {
  2022.     if (overlay_info->exists && overlay_info->window)
  2023.     XResizeWindow(XtDisplay(glw), overlay_info->window,
  2024.               glw->core.width, glw->core.height);
  2025.     if (underlay_info->exists && underlay_info->window)
  2026.     XResizeWindow(XtDisplay(glw), underlay_info->window,
  2027.               glw->core.width, glw->core.height);
  2028.     if (popup_info->exists && popup_info->window)
  2029.     XResizeWindow(XtDisplay(glw), popup_info->window,
  2030.               glw->core.width, glw->core.height);
  2031. }
  2032.  
  2033. /*------------------------------------------------------------------------
  2034.  * ResizeDup
  2035.  *------------------------------------------------------------------------*/
  2036.  
  2037. static void ResizeDup(glw)
  2038.   GlxDrawWidget glw;
  2039. {
  2040. /*
  2041.  * Resize inactive main, overlay, underlay and popup windows if necessary 
  2042.  */
  2043.     /* Single is current so resize double */
  2044.         if (glw->glxDraw.single_buffer)
  2045.     {
  2046.         XResizeWindow(XtDisplay(glw), glw->glxDraw.dbl_buf.info.window,
  2047.                       glw->core.width, glw->core.height);
  2048.             ResizeAux(glw,    &glw->glxDraw.dbl_buf.overlay_info,
  2049.                 &glw->glxDraw.dbl_buf.underlay_info,
  2050.                 &glw->glxDraw.dbl_buf.popup_info);
  2051.         ResizeCallback(glw, glw->glxDraw.dbl_buf.info.window);
  2052.     /* Double is current so resize single */
  2053.     }else{
  2054.         XResizeWindow(XtDisplay(glw), glw->glxDraw.sgl_buf.info.window,
  2055.                       glw->core.width, glw->core.height);
  2056.             ResizeAux(glw,    &glw->glxDraw.sgl_buf.overlay_info,
  2057.                 &glw->glxDraw.sgl_buf.underlay_info,
  2058.                 &glw->glxDraw.sgl_buf.popup_info);
  2059.         ResizeCallback(glw, glw->glxDraw.sgl_buf.info.window);
  2060.     }
  2061. }
  2062.  
  2063. /*------------------------------------------------------------------------
  2064.  * Resize
  2065.  *------------------------------------------------------------------------*/
  2066.  
  2067. static void Resize(glw)
  2068.   GlxDrawWidget glw;
  2069. {
  2070.  
  2071. /* if we get a resize event before being realized, we can't handle it */
  2072.     if (!XtIsRealized((Widget)glw))
  2073.     return;
  2074.  
  2075. /* Resize current overlay, underlay and popup planes if necessary */
  2076.     ResizeAux(glw, &glw->glxDraw.overlay_info,
  2077.            &glw->glxDraw.underlay_info,
  2078.            &glw->glxDraw.popup_info);
  2079.  
  2080.     if (glw->glxDraw.provide_Sbuffer || glw->glxDraw.provide_StereoBuffer)
  2081.     {
  2082. /* Resize secondary window */
  2083.     ResizeDup(glw);
  2084.  
  2085. /* Resize callback for current window */
  2086.         ResizeCallback(glw, XtWindow((Widget) glw));
  2087.     }else
  2088.         ResizeCallback(glw, XtWindow((Widget) glw));
  2089. }
  2090.  
  2091. /*------------------------------------------------------------------------
  2092.  * Destroy
  2093.  *------------------------------------------------------------------------*/
  2094.  
  2095. static void Destroy(glw)    
  2096.   GlxDrawWidget glw;
  2097. {
  2098. #ifdef USE_GL
  2099.     XtFree((char *)glw->glxDraw.config);
  2100. #endif /* USE_GL */
  2101.     if (glw->glxDraw.overlay_info.exists)
  2102.     {
  2103.     _XtUnregisterWindow(glw->glxDraw.overlay_info.window,glw);
  2104.     glw->glxDraw.overlay_info.exists = FALSE;
  2105.     glw->glxDraw.overlay_info.window = NULL;
  2106.     /*The overlay window will be automatically destroyed when the
  2107.      *widget window is actually destroyed
  2108.      */
  2109.     }
  2110.     if (glw->glxDraw.underlay_info.exists)
  2111.     {
  2112.     _XtUnregisterWindow(glw->glxDraw.underlay_info.window,glw);
  2113.     glw->glxDraw.underlay_info.exists = FALSE;
  2114.     glw->glxDraw.underlay_info.window = NULL;
  2115.     /*The underlay window will be automatically destroyed when the
  2116.      *widget window is actually destroyed
  2117.      */
  2118.     }
  2119.     if (glw->glxDraw.popup_info.exists)
  2120.     {
  2121.     _XtUnregisterWindow(glw->glxDraw.popup_info.window,glw);
  2122.     glw->glxDraw.popup_info.exists = FALSE;
  2123.     glw->glxDraw.popup_info.window = NULL;
  2124.     /*The popup window will be automatically destroyed when the
  2125.      *widget window is actually destroyed
  2126.      */
  2127.     }
  2128. #ifdef USE_GL
  2129.     GLXunlink(XtDisplay((Widget) glw), XtWindow((Widget) glw));
  2130. #else
  2131. #endif /* USE_GL */
  2132. }
  2133.  
  2134. /*------------------------------------------------------------------------
  2135.  * glxInput
  2136.  *   Action routine for keyboard and mouse events
  2137.  *   ARGSUSED
  2138.  *------------------------------------------------------------------------*/
  2139.  
  2140. static void glxInput (glw, event, params, num_params)
  2141.   GlxDrawWidget glw;
  2142.   XEvent *event;
  2143.   String *params;        /* unused */
  2144.   Cardinal *num_params;        /* unused */
  2145. {
  2146.    GlxDrawCallbackStruct cb;
  2147.    
  2148.    cb.reason = GlxCR_INPUT;
  2149.    cb.event = event;
  2150.    cb.window = XtWindow(glw);
  2151. #ifdef USE_GL
  2152.    cb.buffer = GLX_NORMAL;
  2153. #else
  2154.    cb.context  = glw->glxDraw.context;
  2155. #endif /* USE_GL */
  2156.    XtCallCallbackList ((Widget) glw, glw->glxDraw.input_callback, &cb);
  2157. }
  2158.  
  2159. /*------------------------------------------------------------------------
  2160.  * auxwindow_destroyed
  2161.  *   If the user explicitly destroys the overlay or underlay windows,
  2162.  *   clean up
  2163.  *------------------------------------------------------------------------*/
  2164.  
  2165. static void auxwindow_destroyed(glw, client_data, event)
  2166.   GlxDrawWidget glw;
  2167.   caddr_t client_data;
  2168.   XEvent *event;
  2169. {
  2170.     if (event->type == DestroyNotify && event->xdestroywindow.window)
  2171.     {
  2172.     if (glw->glxDraw.overlay_info.exists &&
  2173.         event->xdestroywindow.window == glw->glxDraw.overlay_info.window)
  2174.     {
  2175.         _XtUnregisterWindow(glw->glxDraw.overlay_info.window,glw);
  2176.         glw->glxDraw.overlay_info.exists = FALSE;
  2177.         glw->glxDraw.overlay_info.window = 0;
  2178.     }
  2179.     if (glw->glxDraw.underlay_info.exists &&
  2180.         event->xdestroywindow.window == glw->glxDraw.underlay_info.window)
  2181.     {
  2182.         _XtUnregisterWindow(glw->glxDraw.underlay_info.window,glw);
  2183.         glw->glxDraw.underlay_info.exists = FALSE;
  2184.         glw->glxDraw.underlay_info.window = 0;
  2185.     }
  2186.     if (glw->glxDraw.popup_info.exists &&
  2187.         event->xdestroywindow.window == glw->glxDraw.popup_info.window)
  2188.     {
  2189.         _XtUnregisterWindow(glw->glxDraw.popup_info.window,glw);
  2190.         glw->glxDraw.popup_info.exists = FALSE;
  2191.         glw->glxDraw.popup_info.window = 0;
  2192.     }
  2193.     }
  2194. }
  2195.  
  2196. #ifdef __GLX_MOTIF
  2197.  
  2198. /*------------------------------------------------------------------------
  2199.  * GlxCreateMDraw
  2200.  *   Provide a Motif-style create routine
  2201.  *------------------------------------------------------------------------*/
  2202.  
  2203. Widget GlxCreateMDraw(parent, name, arglist, argcount)
  2204.   Widget parent;
  2205.   char *name;
  2206.   ArgList arglist;
  2207.   Cardinal argcount;
  2208. {
  2209.     return (XtCreateWidget (name, glxMDrawWidgetClass, parent, arglist,
  2210.                 argcount));
  2211. }
  2212. #endif
  2213.  
  2214.